#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cstdio>

using namespace std;
#include "Pet.h"
#include "Command.h"


//Command methods
//default constructor
Command::Command()
{

}
//deconstructor
Command::~Command()
{

}
//constructor with input
Command::Command(ifstream & infile)
{

}
void Command::Extract(ifstream& infile) throw (TokenError)
{
     string opentkn, closetkn;
     infile >> opentkn;
     if(opentkn!="Command{") throw TokenError("Invalid open token", "Command::Extract");
     Get(infile);
     infile >> closetkn;
     if(closetkn!="}Command") throw TokenError("Invalid close token", "Command::Extract");

}
void Command::Execute( ostream& fout) throw (AppError)
{
     if (command=="mate!")
     {
        dog1.Perform(command, fout, dog2);
     }
     else
     {
         if(checker=="Dog{")            //handles differentiation between cat/dog
             dog1.Perform(command, fout);
          else
               if(checker=="Cat{")
                  cat.Perform(command, fout);
               else
                    if(checker=="Pet{")
                       pet.Perform(command, fout);
     }
}
void  Command::Insert( ostream& fout )
{
      fout << endl;
      fout << "Command{ ";
      Put( fout );
      fout << " }Command "<<endl;
      Execute(fout);
}

void  Command::Get( ifstream& infile) throw (TokenError)
{
      infile >>checker;
      if(checker=="action:")
      {
          infile>>command;            //stores what commmand it is
          infile>>pet1com;            //should read in pet number
          int temp2=infile.tellg();
          infile>>checker;
          infile.seekg(temp2);
          if(checker=="Dog{")            //handles differentiation between cat/dog
             dog1.Extract(infile);
          else
               if(checker=="Cat{")
                  cat.Extract(infile);
               else
                    if(checker=="Pet{")
                       pet.Extract(infile);
                    else
                        throw TokenError("Expected Dog{, Cat{, or Pet{", "Command::Get");
      }
      else
      {

          pet1com = checker;            //sets pet name
          dog1.Extract(infile);       //passes to dog since it should be a dog, only ones who mate
          infile>>checker;               //should be the word action
          infile>>command;            //should be the mate command
          infile>>pet2com;            //should read in pet number
          dog2.Extract(infile);       //passes to dog since it should be a dog, only ones who mate
      }
}
void  Command::Put ( ostream& fout)
{
      if(command=="mate!")
      {
          fout<<pet1com<<" ";
          dog1.Insert(fout);
          fout<<"action: mate! "<<pet2com<<" ";
          dog2.Insert(fout);
      }
      else
      {
          fout<<"action: "<<command<<" "<<pet1com<<" ";
          if(checker=="Dog{")            //handles differentiation between cat/dog
             dog1.Insert(fout);
          else
               if(checker=="Cat{")
                  cat.Insert(fout);
               else
                    if(checker=="Pet{")
                       pet.Insert(fout);
      }

}
